/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.ec.order.remote.RemoteServiceOrderServiceImpl
   Module Description   :

   Date Created      : 2010/1/5
   Original Author   : andy.chuang
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.ec.order.remote;

import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;

import org.apache.commons.lang.time.FastDateFormat;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import com.yaodian100.core.batch.service.BatchJobService;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.common.utils.StringUtils;
import com.yaodian100.core.mail.entity.Mail;
import com.yaodian100.core.mail.service.MailService;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.core.menu.entity.Option;
import com.yaodian100.core.menu.service.MenuService;
import com.yaodian100.core.sms.service.SmsService;
import com.yaodian100.core.template.service.TemplateService;
import com.yaodian100.ec.category.entity.Category;
import com.yaodian100.ec.cobranding.service.DPNService;
import com.yaodian100.ec.common.EcConstant;
import com.yaodian100.ec.common.EnvParameters;
import com.yaodian100.ec.generate.service.GenerateOrderService;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.order.entity.OrderMemo;
import com.yaodian100.ec.order.entity.OrderProduct;
import com.yaodian100.ec.order.entity.Orders;
import com.yaodian100.ec.order.entity.ServiceOrderDetail;
import com.yaodian100.ec.order.entity.ServiceOrderProduct;
import com.yaodian100.ec.order.entity.ServiceOrders;
import com.yaodian100.ec.order.service.OrderService;
import com.yaodian100.ec.order.service.ServiceOrderService;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.entity.SpecificationInventory;
import com.yaodian100.ec.product.service.ProductService;

/**
 * @author andy.chuang
 * 
 */
public class RemoteOrderServiceImpl implements RemoteOrderService {
	private static Logger LOGGER = LoggerFactory.getLogger(RemoteOrderServiceImpl.class);
	@Autowired
	private BaseManager baseMgr;
	@Autowired
	private ProductService productService;
	@Autowired
	private GenerateOrderService generateOrderService;
	@Resource
	private BatchJobService batchJobService;
	@Resource
	private OrderService orderService;
	@Resource
	private TemplateService velocityService;
	@Resource
	private MailService mailService;
	@Resource
	private MenuService menuService;
	@Resource
	private EnvParameters envParameters;
	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Resource
	private ServiceOrderService serviceOrderService;

	@Resource
	private MemberService memberService;

	@Resource
	private DPNService dpnService;

	@Autowired
	private SmsService smsService;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.order.remote.RemoteServiceOrderService#cancelOrder()
	 */
	@Override
	public String cancelOrder(Integer batchSize) {
		Calendar calendarForOnlinePay = Calendar.getInstance();
		// calendarForOnlinePay.add(Calendar.DAY_OF_MONTH, -3);
		Calendar calendarForWire = Calendar.getInstance();
		calendarForWire.add(Calendar.DAY_OF_MONTH, -3);

		DetachedCriteria dc = DetachedCriteria.forClass(Orders.class);
		dc.add(Restrictions.eq("orderSt", "10"));
		dc.add(Restrictions.eq("paymentSt", "00"));
		// dc.add(Restrictions.in("paymentTp", new String[] { "10", "20", "50" }));
		// dc.add(Restrictions.le("deadline", calendarForOnlinePay.getTime()));// 時間到就取消

		// 銀行，郵局 過期3天才取消。線上支付 過期直接取消
		dc.add(Restrictions.or(
				Restrictions.and(Restrictions.in("paymentTp", new String[] { "50", "70", "80" }),
						Restrictions.le("deadline", calendarForOnlinePay.getTime())),
				Restrictions.and(Restrictions.in("paymentTp", new String[] { "10", "20" }),
						Restrictions.le("deadline", calendarForWire.getTime()))));
		Object[] orders = null;
		if ((batchSize == null) || (batchSize == -1)) {
			orders = baseMgr.findByCriteria(dc);
		} else {
			orders = baseMgr.findByCriteria(dc, 0, batchSize);
		}
		Map<String, String> memberIds = new HashMap<String, String>();
		for (Object obj : orders) {
			Orders order = (Orders) obj;
			memberIds.put(order.getMemberId(), order.getMemberId());
			try {

				orderService.cancelUnpaidOrderBySystem(order);

			} catch (CoreException e) {
				String message = "cancel order failed, orderId: " + order.getOrderId();
				String execLog = StringUtils.printExecption(message, e);
				return execLog;
			}

		}

		return "true";
	}

	@Override
	public String cancelDPNPickupOrder(Integer batchSize) {
		// StringBuffer sql = new StringBuffer("select order_id  from ec_ordeR_main ");
		// sql.append("where RECEIVER_TP = '30' ");
		// sql.append("AND to_char(LOGISTIC_FINAL_DT,'yyyymmdd') = to_char((SYSDATE-8) ,'yyyymmdd')");
		// sql.append("order by order_dt");
		// List<Map<String, Object>> orders = jdbcTemplate.queryForList(sql.toString());
		//
		// for (Map<String, Object> obj : orders) {
		// Orders order = orderService.get((String) obj.get("order_id"));
		// try {
		// LOGGER.debug(order.getOrderId());
		// returnInventory(order);// 退還數量
		// serviceOrderService.cancelOrderBySystem(order.getOrderId(), "订单" + order.getOrderId() + " 逾期未至门店取货已取消", "订单"
		// + order.getOrderId() + " 逾期未至门店取货已取消", order.getMemberId(), "SYSTEM", order.getB2eId());// 處理禮券，購物金，帳戶餘額
		// memberService.updateOrder2PayBalance(order.getMemberId());
		// dpnService.sendNotice("order.arriveStoreCancel", order);
		//
		// // cobranding-onlylady
		// try {
		// String domainSrc = order.getDomainSrc();
		// if (!domainSrc.endsWith("yaodian100.com")) {
		// if (domainSrc.endsWith("onlylady.com")) {
		// Onlylady ol = new Onlylady();
		// ol.olCancelOrder(order);
		// }
		// }
		// } catch (Exception e) {
		//
		// // e.printStackTrace();
		// }
		// } catch (CoreException e) {
		// LOGGER.warn("cancelDPNPickupOrder failed, orderId: " + order.getOrderId() + "; message:" + e.getMessage());
		// e.printStackTrace();
		// return "fail";
		// }
		//
		// try {
		//
		// } catch (CoreException e) {
		// LOGGER.warn("remindDPNPickup failed, orderId: " + order.getOrderId() + "; message:" + e.getMessage());
		// e.printStackTrace();
		// return "fail";
		// }
		//
		// }

		return "true";
	}

	@Override
	public String remindPayment(Integer batchSize) {
		Calendar calS = Calendar.getInstance();
		calS.add(Calendar.HOUR_OF_DAY, 4);
		Calendar calE = Calendar.getInstance();
		calE.add(Calendar.HOUR_OF_DAY, 6);
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmm");
		String nowS = df.format(calS.getTime());
		String nowE = df.format(calE.getTime());

		StringBuffer sql = new StringBuffer("select order_id  from ec_ordeR_main ");
		sql.append("where ORDER_ST = '10' AND PAYMENT_ST = '00' ");
		sql.append("AND PAYMENT_TP IN ('10','20','50','70','80') ");
		sql.append("AND to_char(DEADLINE,'yyyymmddhh24mi') between ").append(nowS).append(" and ").append(nowE);
		sql.append("order by order_dt");
		List<Map<String, Object>> orders = jdbcTemplate.queryForList(sql.toString());

		for (Map<String, Object> obj : orders) {
			Orders order = orderService.get((String) obj.get("order_id"));
			try {
				// sendMail("order.remindPayment", "订单" + order.getOrderId() + " 未支付提醒", order);
				orderService.remindPayment(order);
			} catch (CoreException e) {
				String message = ("remindPayment failed, orderId: " + order.getOrderId());
				String execLog = StringUtils.printExecption(message, e);
				return execLog;
			}

		}

		return "true";
	}

	@Override
	public String remindPaymentSms(Integer batchSize) {

		StringBuffer sql = new StringBuffer("SELECT ORDER_ID  FROM EC_ORDER_MAIN ");
		sql.append("WHERE ORDER_ST = '10' AND PAYMENT_ST = '00' ");
		sql.append("AND PAYMENT_TP in ('50','70','80') AND RECEIVER_MOBILE IS NOT NULL ");
		sql.append("AND ORDER_DT BETWEEN (SYSDATE - 23/24 - 30/(60*24)) AND SYSDATE ");
		sql.append("ORDER BY ORDER_DT");
		List<Map<String, Object>> orders = jdbcTemplate.queryForList(sql.toString());

		for (Map<String, Object> obj : orders) {
			Orders order = orderService.get((String) obj.get("order_id"));
			try {
				orderService.remindPaymentSMS(order);
			} catch (CoreException e) {
				String message = ("remindPayment failed, orderId: " + order.getOrderId());
				String execLog = StringUtils.printExecption(message, e);
				return execLog;
			}

		}

		return "true";
	}

	@Override
	public String remindDPNPickup(Integer batchSize) {

		StringBuffer sql = new StringBuffer("select order_id  from ec_ordeR_main ");
		sql.append("where RECEIVER_TP = '30' ");
		sql.append("AND to_char(LOGISTIC_FINAL_DT,'yyyymmdd') = to_char((SYSDATE-5) ,'yyyymmdd')");
		sql.append("order by order_dt");
		List<Map<String, Object>> orders = jdbcTemplate.queryForList(sql.toString());

		for (Map<String, Object> obj : orders) {
			Orders order = orderService.get((String) obj.get("order_id"));
			try {
				dpnService.sendNotice("order.arriveStoreRemind", order);
			} catch (CoreException e) {
				String message = "remindDPNPickup failed, orderId: " + order.getOrderId();
				String execLog = StringUtils.printExecption(message, e);
				return execLog;
			}

		}

		return "true";
	}

	@Override
	public String completeOrder(Integer batchSize) {
		Calendar calendarForRemindPay = Calendar.getInstance();
		calendarForRemindPay.add(Calendar.DAY_OF_MONTH, -2);

		StringBuilder sb = new StringBuilder();
		sb.append(" select a.orderId from Orders a where not exists ");
		sb.append("(select 1 from OrderProduct b where b.orderId = a.orderId and ");
		sb.append("(((b.logisticFinalDt > sysdate-15 and b.returnRule not like '%_30') or (b.logisticFinalDt > sysdate-30 and b.returnRule like '%_30')) or b.logisticFinalDt is null)) ");
		sb.append("and a.orderSt = '35'");

		try {
			Object[] orders = baseMgr.customHqlQuery(sb.toString(), null);
			for (Object orderId : orders) {
				orderService.completeOrder((String) orderId);
			}
		} catch (CoreException e) {
			String execLog = StringUtils.printExecption(null, e);
			return execLog;
		}

		return "true";
	}

	private List<SpecificationInventory> getSpecificationInventory(Long prodSpecId, String prodId) {
		CommonCriteria cc = new CommonCriteria();
		cc.addEq("specId", prodSpecId);
		cc.addEq("productId", prodId);

		return productService.getSpecificationInventory(cc);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.order.remote.RemoteOrderService#returnInventoryFromServiceOrder()
	 */
	@Override
	public String returnInventoryFromServiceOrder(Integer batchSize) {
		DetachedCriteria dc = DetachedCriteria.forClass(ServiceOrders.class);
		// status is 'apply'
		dc.add(Restrictions.eq("orderSt", "10"));
		dc.add(Restrictions.eq("srcType", 3));
		Object[] serviceOrders = null;
		if ((batchSize == null) || (batchSize == -1)) {
			serviceOrders = baseMgr.findByCriteria(dc);
		} else {
			serviceOrders = baseMgr.findByCriteria(dc, 0, batchSize);
		}

		for (Object obj : serviceOrders) {
			ServiceOrders so = (ServiceOrders) obj;
			try {
				returnInventoryByServiceOrder(so);
			} catch (CoreException e) {
				String message = (" return inventory by serviceOrder failed, serviceId:" + so.getServiceId());
				String execLog = StringUtils.printExecption(message, e);
				return execLog;
			}
		}
		return "true";
	}

	@Transactional(readOnly = false)
	private void returnInventoryByServiceOrder(ServiceOrders so) throws CoreException {
		Orders order = (Orders) baseMgr.get(Orders.class, so.getOrderId());
		if (order.getPaymentSt().equals("00")) {
			// not pay yet
			so.setOrderSt("90");
		} else {
			so.setOrderSt("20");
		}
		baseMgr.update(so);
		DetachedCriteria dc = DetachedCriteria.forClass(ServiceOrderProduct.class);
		dc.add(Restrictions.eq("serviceId", so.getServiceId()));
		Object[] serviceOrderProducts = baseMgr.findByCriteria(dc);
		for (Object obj : serviceOrderProducts) {
			ServiceOrderProduct op = (ServiceOrderProduct) obj;
			for (ServiceOrderDetail sod : op.getServiceOrderDetail()) {
				List<SpecificationInventory> si = getSpecificationInventory(Long.parseLong(sod.getProdSpecId()),
						sod.getProdId());
				for (SpecificationInventory entity : si) {
					entity.setCancelInventory(entity.getCancelInventory() + sod.getQty());
					productService.saveSpecificationInventory(entity);
				}

			}
		}
	}

	@Override
	public String updateOrderStatus(Order o) {
		try {
			orderService.updateOrderStatus(o);
			return "true";
		} catch (Exception e) {
			String execLog = StringUtils.printExecption(null, e);
			return execLog;
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.order.remote.RemoteOrderService#syncOrder()
	 */
	@Override
	// public String syncOrder(Integer batchSize) {
	// Calendar currentDate = Calendar.getInstance();
	// currentDate.add(Calendar.HOUR_OF_DAY, -2);
	// DetachedCriteria dc = DetachedCriteria.forClass(Orders.class);
	// dc.add(Restrictions.le("syncDt", currentDate.getTime()));
	// dc.add(Restrictions.eq("orderSt", "20"));
	// Object[] orders = null;
	// if (batchSize != null && batchSize.intValue() > 0) {
	// orders = baseMgr.findByCriteria(dc, 0, batchSize);
	// } else if (batchSize == null || batchSize.intValue() == -1) {
	// orders = baseMgr.findByCriteria(dc);
	// }
	//
	// for (Object obj : orders) {
	// Orders order = (Orders) obj;
	// order.setOrderSt("25");
	// orderService.syncOrder(order);
	// }
	// return "true";
	// }
	public String syncOrder(Integer batchSize) {

		Calendar currentDate = Calendar.getInstance();
		currentDate.add(Calendar.HOUR_OF_DAY, -1);

		Calendar currentDateCreditCard = Calendar.getInstance();
		currentDateCreditCard.add(Calendar.HOUR_OF_DAY, -8);

		// DetachedCriteria dc = DetachedCriteria.forClass(Orders.class);
		// dc.add(Restrictions.le("syncDt", currentDate.getTime()));
		// // 已付款
		// dc.add(Restrictions.eq("paymentSt", "10"));
		// // 客戶自行取消或等待配貨
		// dc.add(Restrictions.or(Restrictions.eq("orderSt", "81"), Restrictions.eq("orderSt", "20")));
		String hql = "from Orders where  ((syncDt <=? and paymentTp in (?,?)) or (syncDt <=? and paymentTp not in (?,?)))  and isSync!=?  and "
				+ "((paymentTp = ? and orderSt=? and paymentSt=?) or  (paymentTp = ? and orderSt=? and paymentSt=?) or  (paymentSt=? and (orderSt=? or orderSt=?))) and (tuangouId is null or (tuangouId is not null and isTuangouSync = ?))";
		List list = new ArrayList();
		list.add(currentDateCreditCard.getTime());
		list.add("70");
		list.add("80");
		list.add(currentDate.getTime());// syncDt
		list.add("70");
		list.add("80");
		list.add(true);// isSync
		list.add("60");// (paymentTp
		list.add("20");// orderSt
		list.add("00");// paymentSt)
		list.add("30");// (paymentTp
		list.add("20");// orderSt
		list.add("00");// paymentSt)
		list.add("10");// (paymentSt
		list.add("20");// (orderSt
		list.add("81");// orderSt))
		list.add(true);// isTuangouSync
		Object[] orders = null;

		if ((batchSize != null) && (batchSize.intValue() > 0)) {
			orders = baseMgr.queryByHql(hql, list.toArray(), 0, batchSize);
		} else if ((batchSize == null) || (batchSize.intValue() == -1)) {
			orders = baseMgr.queryByHql(hql, list.toArray());
		}
		try {
			for (Object obj : orders) {

				Orders order = (Orders) obj;
				orderService.syncOrder(order);
			}
		} catch (Exception e) {
			String execLog = StringUtils.printExecption(null, e);
			return execLog;
		}

		return "true";
	}

	@Override
	public String syncOrderShippingDelay(String inputOrderIds) {
		List<String> orderIds = new ArrayList<String>(Arrays.asList(StringUtils.split(inputOrderIds, ",")));
		List<String> successR = new ArrayList<String>();
		List<String> failR = new ArrayList<String>();
		List<String> failOrder = new ArrayList<String>(orderIds);// 採正面列表，預設是失敗
		List<String> products = new ArrayList<String>();
		// 赠品资料
		Properties props = new java.util.Properties();

		try {
			// 讀取贈品資料
			props.load((new URL("http://localhost/static/server/giftfordelay.properties")).openStream());
			products = Arrays.asList(StringUtils.split(props.getProperty("gifts"), ","));
			int i = 0;
			Product prod = productService.get(products.get(i));

			Category category = (Category) baseMgr.get(Category.class, Long.valueOf(prod.getMainCategoryID()));
			String categoryPath = category.getCategoryPath();

			for (String orderId : orderIds) {
				orderId = StringUtils.trimToEmpty(orderId);
				boolean redo = false;
				do {
					redo = false;
					try {
						Orders order = orderService.addPromoteProductAndResync(orderId, products.get(i), categoryPath);
						if (null != order) {
							successR.add("" + orderId + ", " + products.get(i));
							failOrder.remove(orderId);// 當成功時就將資料從失敗名單中移除
						}

						redo = false;

					} catch (CoreException e) {
						failR.add("赠品商编:" + products.get(i) + ",错误讯息:" + e.getMessage() + ":" + e.getParameter());
						if ("errors.specInventory.product.zero".equals(e.getMessage())) {
							// 失敗庫存不足, 繼續試加入下一筆的商品
							i++;
							if (i >= products.size()) {
								return "Gift not available";
							}
							prod = productService.get(products.get(i));
							category = (Category) baseMgr.get(Category.class, Long.valueOf(prod.getMainCategoryID()));
							categoryPath = category.getCategoryPath();
							redo = true;
						} else if ("errors.order.verify".equals(e.getMessage())) {
							// 訂單可能已经重复执行, 試下一筆
							redo = false;
						} else {
							// 訂單狀態問題, 試下一筆
							redo = false;
						}

					} catch (Exception e) {
						// 其他原因, 試下一筆
						System.out.println(e.getMessage());
						failR.add("赠品商编:" + products.get(i) + ",错误讯息:" + e.getMessage());
						redo = false;
					}

				} while (redo);
			}

		} catch (Exception e) {
			failR.add("错误讯息:" + e.getMessage());
			failR.add("赠品讯息:" + products);
			e.printStackTrace();
		} finally {

			// StringBuffer mailBody = new StringBuffer();
			String mailSubject = "";
			String mailTo = "afra.chou@yaodian100.com,eric.lin@yaodian100.com,patience.chang@yaodian100.com,bella.huang@yaodian100.com,yaote.tsai@yaodian100.com";
			// String mailTo = "afra.chou@yaodian100.com";

			StringBuffer inventoryInfo = new StringBuffer("<br>赠品库存资料如下:<br>");
			for (String productId : products) {
				productId = StringUtils.trimToEmpty(productId);
				for (SpecificationInventory siTmp : productService.getSpecificationInventoryMap(productId).values()) {
					inventoryInfo.append("商品编号:").append(siTmp.getProductId()).append(",规格编号").append(siTmp.getSpecId())
							.append(",还有数量:").append(siTmp.getInventory().intValue()).append("<br>");
				}
			}

			if (successR.size() > 0) {
				StringBuffer sucessMailBody = new StringBuffer();
				mailSubject = EcConstant.PATTERN_DATE_FORMAT.format(new Date()) + "延迟发货的订单资料_成功";
				sucessMailBody.append("订单编号, 赠品商编<br>");
				for (String successInfo : successR) {
					sucessMailBody.append(successInfo).append("<br>");
				}
				Mail sucessMail = new Mail(mailSubject, sucessMailBody.toString() + inventoryInfo.toString(), mailTo, "");
				sucessMail.setFrom(envParameters.getEmailFromSystem());
				mailService.save(sucessMail);
			}

			if (failOrder.size() > 0) {
				StringBuffer failMailBody = new StringBuffer();
				mailSubject = EcConstant.PATTERN_DATE_FORMAT.format(new Date()) + "延迟发货的订单资料_失败";
				failMailBody.append("失败订单:").append(failOrder).append("<br>");
				for (String failInfo : failR) {
					failMailBody.append(failInfo).append("<br>");
				}
				// 有贈品庫存資料才需要append上去（可能因為商品編號有問題而沒有庫存資料）
				if ("<br>赠品库存资料如下:<br>".length() < inventoryInfo.toString().length()) {
					failMailBody.append(inventoryInfo.toString());
				}
				Mail failMail = new Mail(mailSubject, failMailBody.toString(), mailTo, "");
				failMail.setFrom(envParameters.getEmailFromSystem());
				mailService.save(failMail);
			}

		}

		return "true";
	}

	@Override
	public String syncOrderShippingDelayBonus(String inputOrderIds) {
		List<String> orderIds = new ArrayList<String>(Arrays.asList(StringUtils.split(inputOrderIds, ",")));
		List<String> failR = new ArrayList<String>();
		List<String> successR = new ArrayList<String>();
		List<String> failOrder = new ArrayList<String>(orderIds);// 採正面列表，預設是失敗

		for (String orderId : orderIds) {
			try {
				orderId = StringUtils.trimToEmpty(orderId);

				Orders order = orderService.addBonusForDelayOrder(orderId);
				if (null != order) {
					failOrder.remove(orderId);// 當成功時就將資料從失敗名單中移除
					successR.add(orderId);
				}
			} catch (CoreException e) {
				failR.add("错误讯息:" + e.getMessage());
			}
		}

		String mailSubject = "";
		String mailTo = "apple.chang@yaodian100.com,eric.lin@yaodian100.com,patience.chang@yaodian100.com,bella.huang@yaodian100.com,yaote.tsai@yaodian100.com";

		StringBuffer inventoryInfo = new StringBuffer();

		if (successR.size() > 0) {
			StringBuffer sucessMailBody = new StringBuffer();
			mailSubject = EcConstant.PATTERN_DATE_FORMAT.format(new Date()) + "延迟发货的订单资料_成功";
			sucessMailBody.append("订单编号<br>");
			for (String successInfo : successR) {
				sucessMailBody.append(successInfo).append("<br>");
			}
			Mail sucessMail = new Mail(mailSubject, sucessMailBody.toString() + inventoryInfo.toString(), mailTo, "");
			sucessMail.setFrom(envParameters.getEmailFromSystem());
			mailService.save(sucessMail);
		}

		if (failOrder.size() > 0) {
			StringBuffer failMailBody = new StringBuffer();
			mailSubject = EcConstant.PATTERN_DATE_FORMAT.format(new Date()) + "延迟发货的订单资料_失败";
			failMailBody.append("失败订单:<br>");
			for (int i = 0; i < failOrder.size(); i++) {
				failMailBody.append(failOrder.get(i));
				failMailBody.append(" ").append(failR.get(i)).append("<br>");
			}
			Mail failMail = new Mail(mailSubject, failMailBody.toString(), mailTo, "");
			failMail.setFrom(envParameters.getEmailFromSystem());
			mailService.save(failMail);
		}

		return "true";
	}

	public String remindTuangouClose(String date) {
		String result = "";
		StringBuffer sb = new StringBuffer(
				"select o from Orders o, ShelfTuangou sh where o.tuangouId = sh.tuangouId and sh.endDeate < current_date and sh.tuangouStatus = '0'");
		try {
			Object[] orders = baseMgr.customHqlQuery(sb.toString(), null);
			for (Object order : orders) {

				result += orderService.remindTuangouClose((Orders) order);

			}
			if (StringUtils.isBlank(result)) {
				result = "true";
			}
		} catch (CoreException e) {
			String execLog = StringUtils.printExecption(null, e);
			return execLog;
		}
		return result;
	}

	public String split(String orderId, String orderProdIds) {
		String result = "true";
		try {
			result = orderService.splitOrder(orderId, orderProdIds);
		} catch (Exception e) {
			String execLog = StringUtils.printExecption(null, e);
			return execLog;
		}
		return result;
	}

	@Override
	public String preSendOrderDelayNoticeBO(String orderIds) {
		try {
			String[] orders = orderIds.split(",");
			for (String orderId : orders) {
				if (orderId.length() == 0) {
					continue;
				}
				Orders order = (Orders) baseMgr.get(Orders.class, orderId);
				Member member = (Member) baseMgr.get(Member.class, order.getMemberId());

				// 取得最大天数
				StringBuffer sql = new StringBuffer("select max(bo_to_wh_date) from ec_order_detail where order_id = '"
						+ order.getOrderId() + "'");
				int days = jdbcTemplate.queryForInt(sql.toString());

				Map<String, Object> contentMap = new HashMap<String, Object>();
				contentMap.put("memberName", member.getLoginId());
				contentMap.put("orderId", orderId);
				contentMap.put("basehref", "http://" + order.getDomainSrc());
				contentMap.put("days", days);
				Mail mail = velocityService.formatToMail("delay_pre_notice_bo", contentMap);

				mail.setFrom(envParameters.getEmailFromSystem());
				mail.setTo(order.getReceiverEmail());

				mailService.save(mail);

				if (member.getMobile() != null) {
					StringBuffer smsMsg = new StringBuffer();
					smsMsg
							.append("亲爱的耀点100用户，您提交的订单")
							.append(orderId)
							.append(
									"预计需"
											+ (days > 5 ? (days - 4) + "~" + (days - 3) : "1~2")
											+ "日备货，备货期间，网站会及时更新订单状态以便您在线查询。我们对由此带来的不便深感歉意并请您耐心等候。您若有任何疑问或需求，欢迎致电客服热线4001-168-100。 我们将竭诚为您服务！【耀点100】");
					this.smsService.sendSms(member.getMobile(), smsMsg.toString(), orderId);
				}
			}
		} catch (Exception e) {
			String execLog = StringUtils.printExecption(null, e);
			return execLog;
		}
		return "true";

	}

	@Override
	public String preSendOrderDelayNoticeStock(String orderIds) {
		try {
			String[] orders = orderIds.split(",");
			for (String orderId : orders) {
				if (orderId.length() == 0) {
					continue;
				}
				Orders order = (Orders) baseMgr.get(Orders.class, orderId);
				Member member = (Member) baseMgr.get(Member.class, order.getMemberId());

				// 取得最大天数
				StringBuffer sql = new StringBuffer("select max(delivery_day) from ec_order_detail where order_id = '"
						+ order.getOrderId() + "'");
				int days = jdbcTemplate.queryForInt(sql.toString());

				Map<String, Object> contentMap = new HashMap<String, Object>();
				contentMap.put("memberName", member.getLoginId());
				contentMap.put("orderId", orderId);
				contentMap.put("days", days);
				contentMap.put("basehref", "http://" + order.getDomainSrc());
				Mail mail = velocityService.formatToMail("delay_pre_notice_stock", contentMap);

				mail.setFrom(envParameters.getEmailFromSystem());
				mail.setTo(order.getReceiverEmail());

				mailService.save(mail);

				if (member.getMobile() != null) {
					StringBuffer smsMsg = new StringBuffer();
					smsMsg
							.append("亲爱的耀点100用户，您提交的订单")
							.append(orderId)
							.append(
									"预计需"
											+ (days > 5 ? (days - 4) + "~" + (days - 3) : "1~2")
											+ "日备货，备货期间，网站会及时更新订单状态以便您在线查询。我们对由此带来的不便深感歉意并请您耐心等候。您若有任何疑问或需求，欢迎致电客服热线4001-168-100。 我们将竭诚为您服务！【耀点100】");
					this.smsService.sendSms(member.getMobile(), smsMsg.toString(), orderId);
				}
			}
		} catch (Exception e) {
			String execLog = StringUtils.printExecption(null, e);
			return execLog;
		}
		return "true";

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.order.remote.RemoteOrderService#updateLogisticInfo(java.lang.String, java.lang.String,
	 * java.lang.String)
	 */
	@Override
	public String updateLogisticInfo(String orderId, String logisticCompany, String logisticRefNum,
			String serviceOrderId, String orderProdId) {
		if ((StringUtils.isNotBlank(orderId) || StringUtils.isNotBlank(serviceOrderId))
				&& StringUtils.isNotBlank(logisticCompany) && StringUtils.isNotBlank(logisticRefNum)
				&& StringUtils.isNotBlank(orderProdId)) {
			String opIdStr[] = StringUtils.split(orderProdId, ",");
			List<Long> opIds = new ArrayList<Long>();
			for (int i = 0; i < opIdStr.length; i++) {
				opIds.add(new Long(opIdStr[i]));
			}
			if (StringUtils.isNotBlank(serviceOrderId)) {
				CommonCriteria cc = new CommonCriteria();
				cc.addEq("serviceId", serviceOrderId);
				cc.addIn("serviceProdId", opIds);
				List<ServiceOrderProduct> sops = serviceOrderService.getServiceOrderProdList(0, -1, cc, null);
				if (sops.size() > 0) {
					for (ServiceOrderProduct sop : sops) {
						sop.setLogisticCompany(logisticCompany);
						sop.setLogisticRefNum(logisticRefNum);
						serviceOrderService.saveServiceOrderProd(sop);
					}
				} else {
					return "服务单编号不存在，服务单编号:" + serviceOrderId;
				}
			}
			if (StringUtils.isNotBlank(orderId)) {
				Orders order = orderService.get(orderId);
				if (null != order) {
					try {
						List<OrderProduct> ops = order.getOrderProduct();
						for (OrderProduct op : ops) {
							if (opIds.indexOf(op.getOrderProdId()) >= 0) {
								op.setLogisticCompany(logisticCompany);
								op.setLogisticRefNum(logisticRefNum);
							}
						}
						orderService.save(order);
						OrderMemo orderMemo = new OrderMemo();
						orderMemo.setOrderId(order.getOrderId());
						orderMemo.setMemo("后台更新物流资讯");
						orderService.saveOrderMemo(orderMemo);
					} catch (Exception e) {
						return e.getMessage();
					}

				} else {
					return "订单编号不存在，订单编号:" + orderId;
				}
			}
		} else {
			return "订单编号，物流商代码，物流单编号资料不齐全";
		}
		return "true";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.order.remote.RemoteOrderService#remindExceptionOrders(java.lang.Integer)
	 */
	@Override
	public String remindExceptionOrders(Integer batchSize) {
		List<Orders> orders = null;
		CommonCriteria crit = new CommonCriteria();
		crit.addEq("exceptionFlag", "Y");
		if ((batchSize == null) || (batchSize == -1)) {
			orders = orderService.getList(0, -1, crit, new String[] { "createDate" });
		} else {
			orders = orderService.getList(0, batchSize, crit, new String[] { "createDate" });
		}
		if ((null != orders) && (orders.size() > 0)) {
			StringBuffer sb = new StringBuffer();
			for (Orders order : orders) {
				sb.append(order.getOrderId()).append(",");
			}
			Mail mail = new Mail(
					FastDateFormat.getInstance(EcConstant.PATTERN_DATE).format(DateUtil.getToday()) + "未同步之異常订單", "订单编号："
							+ sb.toString(), "fe@yaodian100.com", "");
			mail.setFrom(envParameters.getEmailFromSystem());
			mailService.save(mail);
			sb.setLength(0);
		}

		remindOrder("yaodian100.tmall.com");
		remindOrder("yaodian100.360buy.com");
		remindOrder("yaodian100.yihaodian.com");
		remindOrder("");

		return "true";
	}

	private void remindOrder(String domain) {
		try {
			Option mailAddr = null;
			CommonCriteria crit = new CommonCriteria();
			if (StringUtils.isNotBlank(domain)) {
				crit.addEq("domainSrc", domain);
				Menu menu = menuService.get("SystemValue");
				mailAddr = menu.getOptions().get("orderWarnMail_" + StringUtils.split(domain, ".")[1]);
			} else {
				Menu menu = menuService.get("SystemValue");
				mailAddr = menu.getOptions().get("orderWarnMail");
			}
			crit.addIn("orderSt", Arrays.asList("00", "05", "10", "20", "25"));
			crit.addLe("paymentDt", DateUtil.getTodayAddDays(-1).getTime());
			crit.addEq("paymentSt", "10");
			List<Orders> orders = orderService.getList(0, -1, crit, new String[] { "domainSrc", "paymentDt" });
			crit = new CommonCriteria();
			if (StringUtils.isNotBlank(domain)) {
				crit.addEq("domainSrc", domain);
			}
			crit.addIn("orderSt", Arrays.asList("00", "05", "10", "20", "25"));
			crit.addLe("createDate", DateUtil.getTodayAddDays(-1).getTime());
			crit.addIn("paymentTp", Arrays.asList("30", "60"));
			orders.addAll(orderService.getList(0, -1, crit, new String[] { "domainSrc", "paymentDt" }));

			if ((null != orders) && (orders.size() > 0)) {
				Map objs = new HashMap();
				objs.put("orders", orders);
				objs.put("orderStMap", menuService.get("Order.status.md").getOptions());
				objs.put("paymentTpMap", menuService.get("Order.PaymentTp").getOptions());
				Mail mail = velocityService.formatToMail("warn/expireOrders", objs);

				mail.setFrom(envParameters.getEmailFromSystem());
				if (mailAddr != null) {
					String toList = mailAddr.getMemo1();
					for (String s : StringUtils.split(toList, ",")) {
						mail.addTo(null, s);
					}
					String ccList = mailAddr.getMemo2();
					for (String s : StringUtils.split(ccList, ",")) {
						mail.addCc(null, s);
					}
				}
				if (StringUtils.isNotBlank(mail.getTo())) {
					mailService.save(mail);
				} else {
					LOGGER.error(mail.getBody());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
